﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ItemsUseCase.cs" company="">
//   
// </copyright>
// <summary>
//   The items use case.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Libium.UseCases
{
    using System;
    using System.Collections.Generic;
    using System.Linq;

    // TODO Rename
    /// <summary>
    /// The items use case.
    /// </summary>
    /// <typeparam name="T">
    /// </typeparam>
    public class ItemsUseCase<T> : CompoundUseCase, IItemsUseCase
        where T : IUseCase
    {
        #region Fields

        /// <summary>
        ///   The _items.
        /// </summary>
        private readonly List<ItemsUseCaseItem> _items = new List<ItemsUseCaseItem>();

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="ItemsUseCase{T}"/> class.
        /// </summary>
        /// <param name="parent">
        /// The parent. 
        /// </param>
        /// <param name="service">
        /// The service. 
        /// </param>
        public ItemsUseCase(ICompoundUseCase parent, IUseCaseInstanceService service)
            : base(parent, service)
        {
        }

        #endregion

        #region Public Events

        /// <summary>
        ///   The item added.
        /// </summary>
        public event Action<IItemsUseCase, ItemsUseCaseItem> ItemAdded;

        /// <summary>
        ///   The item deleted.
        /// </summary>
        public event Action<IItemsUseCase, ItemsUseCaseItem> ItemDeleted;

        #endregion

        #region Public Properties

        /// <summary>
        ///   Gets the item use cases.
        /// </summary>
        public virtual IEnumerable<T> ItemUseCases
        {
            get
            {
                return _items.Select((i) => i.UseCase).Cast<T>();
            }
        }

        /// <summary>
        ///   Gets the items.
        /// </summary>
        public virtual IEnumerable<ItemsUseCaseItem> Items
        {
            get
            {
                return _items;
            }
        }

        #endregion

        #region Public Methods and Operators

        /// <summary>
        /// The add item.
        /// </summary>
        /// <param name="typeName">
        /// The type name. 
        /// </param>
        /// <param name="useCase">
        /// The use case. 
        /// </param>
        protected void AddItemUseCaseWithoutModify(string typeName, IUseCase useCase)
        {
            //TODO Remove method, use suspend section instead
            var item = new ItemsUseCaseItem { TypeName = typeName, UseCase = useCase };
            _items.Add(item);
            AddUseCase(item.UseCase);
            OnItemUseCaseAdded(item);
        }

        public void AddItemUseCase(string typeName, IUseCase useCase)
        {
            AddItemUseCaseWithoutModify(typeName, useCase);
            Modified = true;
        }

        protected override void OnUseCaseDeleted(IUseCase useCase)
        {
            var item = _items.FirstOrDefault(i => i.UseCase == useCase);
            if (item != null)
            {
                _items.Remove(item);
                OnItemUseCaseDeleted(item);
                Modified = true;
            }
            //Must be call at the end
            base.OnUseCaseDeleted(useCase);
        }

        #endregion

        #region Methods

        /// <summary>
        /// The on item use case added.
        /// </summary>
        /// <param name="item">
        /// The item. 
        /// </param>
        protected virtual void OnItemUseCaseAdded(ItemsUseCaseItem item)
        {
            if (ItemAdded != null)
            {
                ItemAdded(this, item);
            }
        }

        /// <summary>
        /// The on item use case deleted.
        /// </summary>
        /// <param name="item">
        /// The item. 
        /// </param>
        protected virtual void OnItemUseCaseDeleted(ItemsUseCaseItem item)
        {
            if (ItemDeleted != null)
            {
                ItemDeleted(this, item);
            }
        }

        #endregion
    }
}